using System;
using System.Web;
using System.Web.Mvc;
using Dimebrain.TweetSharp.Extensions;
using Dimebrain.TweetSharp.Fluent;
using Dimebrain.TweetSharp.Model;

namespace AreYouFollowingMe.Controllers
{
    public class loginController : baseController
    {
        public ActionResult Index()
        {
            var requestToken = Request["oauth_token"];
            var requestVerifier = Request["oauth_verifier"];

            if (requestToken == null)
            {
#if DEBUG
                var request = GetRequestToken("http://localhost:8080/login");
#else
                var request = GetRequestToken("http://ruf.cloudapp.net/login");
#endif
                var authorizeUrl = FluentTwitter.CreateRequest()
                    .Authentication.GetAuthorizationUrl(request.Token);
                return Redirect(authorizeUrl);
            }
            
            // exchange returned request token for access token
            var access = GetAccessToken(requestToken, requestVerifier);

            // make an oauth-authenticated call with the access token,
            // and remember you need to persist this token for this user's auth
            Response.Cookies["auth_token"].Value = HttpUtility.UrlEncode(access.Token);
            Response.Cookies["auth_token"].Expires = DateTime.Now.AddMonths(1);

            Response.Cookies["auth_secret"].Value = HttpUtility.UrlEncode(access.TokenSecret);
            Response.Cookies["auth_secret"].Expires = DateTime.Now.AddMonths(1);
            
            var query = FluentTwitter.CreateRequest()
                .AuthenticateWith(_consumerKey,
                                  _consumerSecret,
                                  access.Token,
                                  access.TokenSecret)
                .Account()
                .VerifyCredentials()
                .AsXml();

            // OAuth is still in Beta, YMMV
            var response = query.Request();

            var identity = response.AsUser();
            if (identity != null)
            {
                Response.Cookies["auth_name"].Value = identity.ScreenName;
                Response.Cookies["auth_name"].Expires = DateTime.Now.AddMonths(1);

                return Redirect("/home");
            }

            var errorString = "Unknown error";
            var error = response.AsError();
            if (error != null)
            {
                errorString = error.ErrorMessage;
            }
            return View((object)errorString);
        }

        public ActionResult SignOut()
        {
            Response.Cookies["auth_name"].Expires = DateTime.Now.AddMonths(-1);
            Response.Cookies["auth_token"].Expires = DateTime.Now.AddMonths(-1);
            Response.Cookies["auth_secret"].Expires = DateTime.Now.AddMonths(-1);
            return RedirectToAction("Index", "Home");
        }

        private OAuthToken GetAccessToken(string requestToken, string verifier)
        {
            var accessToken = FluentTwitter.CreateRequest()
                .Authentication.GetAccessToken(_consumerKey, _consumerSecret, requestToken, verifier);

            var response = accessToken.Request();
            var result = response.AsToken();

            if (result == null)
            {
                var error = response.AsError();
                if (error != null)
                {
                    throw new Exception(error.ErrorMessage);
                }
            }

            return result;
        }

        private OAuthToken GetRequestToken(string callbackUrl)
        {
            var requestToken = FluentTwitter.CreateRequest()
                .Authentication.GetRequestToken(_consumerKey, _consumerSecret, callbackUrl);

            var response = requestToken.Request();
            var result = response.AsToken();

            if (result == null)
            {
                var error = response.AsError();
                if (error != null)
                {
                    throw new Exception(error.ErrorMessage);
                }
            }

            return result;
        }
    }
}
